﻿#include "widget.h"
#include "ui_widget.h"
#include <QValidator>
#include <QHostAddress>
#include <QNetworkInterface>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    startConnect(false);
    on_tcpMode_currentIndexChanged(0);
    initClientSignals();        //初始化客户端信号槽
    initServerSignals();        //初始化服务器信号槽

    QRegExp regx("[0-9]+$");//限制只能数字输入
    QValidator *validator = new QRegExpValidator(regx, this );
    ui->ipAddr1->setValidator( validator );//IP地址的四个字节段
    ui->ipAddr2->setValidator( validator );
    ui->ipAddr3->setValidator( validator );
    ui->ipAddr4->setValidator( validator );
    ui->ipPort->setValidator( validator );//服务器端口号
    this->setWindowTitle("客户端");
}
/*****************************************************************
    on_tcpMode_currentIndexChanged(int index)
    两种模式下，各种控件的状态（hide/show）选择
    获取tcpMode值，选择不同用户状态
******************************************************************/
void Widget::on_tcpMode_currentIndexChanged(int index)
{
    if(index==0)        //clent
    {
        ui->ipPortLabel->setText("服务器端口号:");
        ui->ipAddLabel->show();
        ui->ipAdds->show();
        ui->targetLabel->hide();
        ui->targetObject->hide();
    }
    else
    {
        ui->ipAddLabel->hide();
        ui->ipAdds->hide();
        ui->ipPortLabel->setText("本地端口号:");
    }
}

/*****************************************************************
    on_btn_switch_clicked()
    “打开连接”按钮
    关联函数：startClient()，startServer()，startConnect()
    根据btn_switch->text()和tcpMode上不同状态，选择连接状态
******************************************************************/
void Widget::on_btn_switch_clicked()
{
    bool ret;
    if(ui->btn_switch->text()=="打开连接")
    {
        if(ui->tcpMode->currentIndex()==0)  //启动客户端
        {
            ret=startClient();
        }
        else
        {
            ret=startServer();
        }
        if(ret)
        {
            startConnect(true);
        }
    }
    else
    {
        if(ui->tcpMode->currentIndex()==0)  //启动客户端
        {
            m_client.close();

        }
        else
        {
            if( m_server.isListening() )
            {
                QList<QTcpSocket *> m_tcps = m_server.findChildren<QTcpSocket *>();
                foreach (QTcpSocket *tcp, m_tcps)
                {
                    tcp->close();
                }
                m_server.close();
            }
        }
        startConnect(false);
    }
}

/*****************************************************************
    startConnect(bool ison)
    与“打开连接”按钮关联
    负责按钮不同状态下，授予信息获取状态
******************************************************************/
void Widget::startConnect(bool ison)
{
    if(!ison)
    {
        ui->btn_switch->setStyleSheet("color:blue;border: 1px solid blue");
        ui->btn_switch->setText("打开连接");

        //使能
        ui->ipAddr1->setEnabled(true);
        ui->ipAddr2->setEnabled(true);
        ui->ipAddr3->setEnabled(true);
        ui->ipAddr4->setEnabled(true);
        ui->tcpMode->setEnabled(true);
        ui->ipPort->setEnabled(true);
        ui->localPort->setText("");
    }
    else
    {
        ui->btn_switch->setStyleSheet("color:red;border: 1px solid red");
        ui->btn_switch->setText("关闭连接");
        //失能
        ui->ipAddr1->setEnabled(false);
        ui->ipAddr2->setEnabled(false);
        ui->ipAddr3->setEnabled(false);
        ui->ipAddr4->setEnabled(false);
        ui->tcpMode->setEnabled(false);
        ui->ipPort->setEnabled(false);
        targetAddr="";
        targetPort=0;
        ui->sendLenLabel->setText("0");
    }
}

/*****************************************************************
    on_betn_clear_clicked()
    “清除接受”按钮事件
    清空recvEdit（信息接受框）内容
******************************************************************/
void Widget::on_betn_clear_clicked()
{
   ui->recvEdit->clear();
   targetAddr="";
   targetPort=0;
}

/*****************************************************************
    on_btn_send_clicked()
    “发送”按钮事件
    根据tcpMode（状态框）和targetObject（对象下拉框）的状态，给另一方发送信息
******************************************************************/
void Widget::on_btn_send_clicked()
{
    if(ui->btn_switch->text()!="打开连接")
    {
        if(ui->tcpMode->currentIndex()==0)  //客户端
        {
            m_client.write(ui->sendEdit->toPlainText().toLocal8Bit(),ui->sendEdit->toPlainText().toLocal8Bit().length());
        }
        else //服务器端
        {
            if(ui->targetObject->currentText()!="所有对象")
            {
                QList<QTcpSocket *> m_tcps = m_server.findChildren<QTcpSocket *>();
                foreach (QTcpSocket *tcp, m_tcps)
                {
                    if(ui->targetObject->currentText() == tcp->objectName())
                    {
                        tcp->write(ui->sendEdit->toPlainText().toLocal8Bit(),ui->sendEdit->toPlainText().toLocal8Bit().length());
                        break;
                    }
                }
            }
            else            //所有连接上的客户端都发送一遍
            {
                QList<QTcpSocket *> m_tcps = m_server.findChildren<QTcpSocket *>();
                foreach (QTcpSocket *tcp, m_tcps)
                {
                    tcp->write(ui->sendEdit->toPlainText().toLocal8Bit(),ui->sendEdit->toPlainText().toLocal8Bit().length());
                }
            }
        }
    }
}

/*****************************************************************
    ~Widget()
    析构函数
    程序关闭后，输出关闭信息并删除
******************************************************************/
Widget::~Widget()
{
    QList<QTcpSocket *> m_tcps = m_server.findChildren<QTcpSocket *>();
    foreach (QTcpSocket *tcp, m_tcps)
    {
        tcp->close();
    }
    if(m_client.isOpen())
    {
        m_client.close();
         qDebug()<<"m_client close";
    }
    delete ui;
}

/*****************************************************************
    on_tcpMode_activated(const QString &arg1)
    tcpMode（ComboBox）点击事件
    根据点击的选项不同，更改窗体的名字
******************************************************************/
void Widget::on_tcpMode_activated(const QString &arg1)
{
    if(arg1 == "TCP Client")  //启动客户端
    {
        this->setWindowTitle("客户端");
    }
    else if(arg1 == "TCP Server")
    {
        this->setWindowTitle("服务器端");
    }
    else
    {

    }
}
